using FluentValidation;
using Matrix.ServiceDiscovery.Dtos;
using Matrix.ServiceDiscovery.Enums;

namespace Matrix.ServiceDiscovery.Validators
{
    /// <summary>
    /// 创建服务信息验证器
    /// </summary>
    public class CreateServiceInfoValidator : AbstractValidator<CreateServiceInfoDto>
    {
        public CreateServiceInfoValidator()
        {
            RuleFor(x => x.Name)
                .NotEmpty()
                .WithMessage("服务名称不能为空")
                .MaximumLength(100)
                .WithMessage("服务名称长度不能超过100个字符")
                .Matches(@"^[a-zA-Z][a-zA-Z0-9-_]*$")
                .WithMessage("服务名称只能包含字母、数字、连字符和下划线，且必须以字母开头");

            RuleFor(x => x.Version)
                .NotEmpty()
                .WithMessage("服务版本不能为空")
                .MaximumLength(50)
                .WithMessage("服务版本长度不能超过50个字符")
                .Matches(@"^\d+\.\d+(\.\d+)?(-[a-zA-Z0-9]+)?$")
                .WithMessage("服务版本格式不正确，应为语义化版本号（如：1.0.0）");

            RuleFor(x => x.ServiceType)
                .IsInEnum()
                .WithMessage("服务类型无效");

            RuleFor(x => x.Description)
                .MaximumLength(500)
                .WithMessage("服务描述长度不能超过500个字符");

            RuleFor(x => x.ServiceGroup)
                .MaximumLength(100)
                .WithMessage("服务分组长度不能超过100个字符")
                .Matches(@"^[a-zA-Z][a-zA-Z0-9-_]*$")
                .When(x => !string.IsNullOrWhiteSpace(x.ServiceGroup))
                .WithMessage("服务分组只能包含字母、数字、连字符和下划线，且必须以字母开头");
        }
    }

    /// <summary>
    /// 更新服务信息验证器
    /// </summary>
    public class UpdateServiceInfoValidator : AbstractValidator<UpdateServiceInfoDto>
    {
        public UpdateServiceInfoValidator()
        {
            RuleFor(x => x.Name)
                .MaximumLength(100)
                .WithMessage("服务名称长度不能超过100个字符")
                .Matches(@"^[a-zA-Z][a-zA-Z0-9-_]*$")
                .When(x => !string.IsNullOrWhiteSpace(x.Name))
                .WithMessage("服务名称只能包含字母、数字、连字符和下划线，且必须以字母开头");

            RuleFor(x => x.Version)
                .MaximumLength(50)
                .WithMessage("服务版本长度不能超过50个字符")
                .Matches(@"^\d+\.\d+(\.\d+)?(-[a-zA-Z0-9]+)?$")
                .When(x => !string.IsNullOrWhiteSpace(x.Version))
                .WithMessage("服务版本格式不正确，应为语义化版本号（如：1.0.0）");

            RuleFor(x => x.Description)
                .MaximumLength(500)
                .WithMessage("服务描述长度不能超过500个字符");

            RuleFor(x => x.ServiceGroup)
                .MaximumLength(100)
                .WithMessage("服务分组长度不能超过100个字符")
                .Matches(@"^[a-zA-Z][a-zA-Z0-9-_]*$")
                .When(x => !string.IsNullOrWhiteSpace(x.ServiceGroup))
                .WithMessage("服务分组只能包含字母、数字、连字符和下划线，且必须以字母开头");
        }
    }

    /// <summary>
    /// 注册服务实例验证器
    /// </summary>
    public class RegisterServiceInstanceValidator : AbstractValidator<RegisterServiceInstanceDto>
    {
        public RegisterServiceInstanceValidator()
        {
            RuleFor(x => x.ServiceId)
                .NotEmpty()
                .WithMessage("服务ID不能为空");

            RuleFor(x => x.ServiceName)
                .NotEmpty()
                .WithMessage("服务名称不能为空")
                .MaximumLength(100)
                .WithMessage("服务名称长度不能超过100个字符");

            RuleFor(x => x.InstanceId)
                .NotEmpty()
                .WithMessage("实例ID不能为空")
                .MaximumLength(100)
                .WithMessage("实例ID长度不能超过100个字符")
                .Matches(@"^[a-zA-Z0-9-_]+$")
                .WithMessage("实例ID只能包含字母、数字、连字符和下划线");

            RuleFor(x => x.Host)
                .NotEmpty()
                .WithMessage("主机地址不能为空")
                .MaximumLength(255)
                .WithMessage("主机地址长度不能超过255个字符");

            RuleFor(x => x.Port)
                .GreaterThan(0)
                .WithMessage("端口号必须大于0")
                .LessThanOrEqualTo(65535)
                .WithMessage("端口号不能超过65535");

            RuleFor(x => x.Protocol)
                .NotEmpty()
                .WithMessage("协议类型不能为空")
                .Must(protocol => new[] { "HTTP", "HTTPS", "TCP", "UDP", "GRPC" }.Contains(protocol.ToUpper()))
                .WithMessage("协议类型必须是HTTP、HTTPS、TCP、UDP或GRPC之一");

            RuleFor(x => x.Weight)
                .GreaterThan(0)
                .WithMessage("权重必须大于0")
                .LessThanOrEqualTo(1000)
                .WithMessage("权重不能超过1000");

            RuleFor(x => x.Region)
                .MaximumLength(50)
                .WithMessage("区域长度不能超过50个字符")
                .When(x => !string.IsNullOrWhiteSpace(x.Region));

            RuleFor(x => x.Zone)
                .MaximumLength(50)
                .WithMessage("可用区长度不能超过50个字符")
                .When(x => !string.IsNullOrWhiteSpace(x.Zone));

            RuleFor(x => x.Tags)
                .Must(tags => tags == null || tags.Count <= 20)
                .WithMessage("标签数量不能超过20个")
                .When(x => x.Tags != null);

            RuleForEach(x => x.Tags)
                .MaximumLength(50)
                .WithMessage("单个标签长度不能超过50个字符")
                .When(x => x.Tags != null);

            RuleFor(x => x.Metadata)
                .Must(metadata => metadata == null || metadata.Count <= 50)
                .WithMessage("元数据条目数量不能超过50个")
                .When(x => x.Metadata != null);

            RuleForEach(x => x.Metadata)
                .Must(metadata => metadata.Key.Length <= 100 && metadata.Value?.ToString().Length <= 500)
                .WithMessage("元数据键长度不能超过100个字符，值长度不能超过500个字符")
                .When(x => x.Metadata != null);
        }
    }

    /// <summary>
    /// 更新负载均衡配置验证器
    /// </summary>
    public class UpdateLoadBalancingConfigValidator : AbstractValidator<UpdateLoadBalancingConfigDto>
    {
        public UpdateLoadBalancingConfigValidator()
        {
            RuleFor(x => x.Strategy)
                .IsInEnum()
                .When(x => x.Strategy.HasValue)
                .WithMessage("负载均衡策略无效");

            RuleFor(x => x.HealthCheckInterval)
                .GreaterThan(TimeSpan.Zero)
                .When(x => x.HealthCheckInterval.HasValue)
                .WithMessage("健康检查间隔必须大于0");

            RuleFor(x => x.Timeout)
                .GreaterThan(TimeSpan.Zero)
                .When(x => x.Timeout.HasValue)
                .WithMessage("超时时间必须大于0");

            RuleFor(x => x.FailureThreshold)
                .GreaterThan(0)
                .When(x => x.FailureThreshold.HasValue)
                .WithMessage("失败阈值必须大于0");

            RuleFor(x => x.SuccessThreshold)
                .GreaterThan(0)
                .When(x => x.SuccessThreshold.HasValue)
                .WithMessage("成功阈值必须大于0");
        }
    }

    /// <summary>
    /// 查询服务列表验证器
    /// </summary>
    public class GetServiceListInputValidator : AbstractValidator<GetServiceListInput>
    {
        public GetServiceListInputValidator()
        {
            RuleFor(x => x.Keyword)
                .MaximumLength(100)
                .WithMessage("关键词长度不能超过100个字符")
                .When(x => !string.IsNullOrWhiteSpace(x.Keyword));

            RuleFor(x => x.ServiceType)
                .Must(type => string.IsNullOrWhiteSpace(type) || Enum.TryParse<ServiceType>(type, out _))
                .WithMessage("服务类型无效")
                .When(x => !string.IsNullOrWhiteSpace(x.ServiceType));

            RuleFor(x => x.ServiceGroup)
                .MaximumLength(100)
                .WithMessage("服务分组长度不能超过100个字符")
                .When(x => !string.IsNullOrWhiteSpace(x.ServiceGroup));

            RuleFor(x => x.MaxResultCount)
                .GreaterThan(0)
                .WithMessage("最大结果数量必须大于0")
                .LessThanOrEqualTo(1000)
                .WithMessage("最大结果数量不能超过1000");

            RuleFor(x => x.SkipCount)
                .GreaterThanOrEqualTo(0)
                .WithMessage("跳过数量不能小于0");
        }
    }

    /// <summary>
    /// 搜索服务验证器
    /// </summary>
    public class SearchServicesInputValidator : AbstractValidator<SearchServicesInput>
    {
        public SearchServicesInputValidator()
        {
            RuleFor(x => x.Keyword)
                .MaximumLength(100)
                .WithMessage("关键词长度不能超过100个字符")
                .When(x => !string.IsNullOrWhiteSpace(x.Keyword));

            RuleFor(x => x.ServiceTypes)
                .Must(types => types == null || types.Count <= 10)
                .WithMessage("服务类型数量不能超过10个")
                .When(x => x.ServiceTypes != null);

            RuleForEach(x => x.ServiceTypes)
                .Must(type => Enum.TryParse<ServiceType>(type, out _))
                .WithMessage("服务类型无效")
                .When(x => x.ServiceTypes != null);

            RuleFor(x => x.Statuses)
                .Must(statuses => statuses == null || statuses.Count <= 5)
                .WithMessage("服务状态数量不能超过5个")
                .When(x => x.Statuses != null);

            RuleFor(x => x.MaxResultCount)
                .GreaterThan(0)
                .WithMessage("最大结果数量必须大于0")
                .LessThanOrEqualTo(1000)
                .WithMessage("最大结果数量不能超过1000");

            RuleFor(x => x.SkipCount)
                .GreaterThanOrEqualTo(0)
                .WithMessage("跳过数量不能小于0");
        }
    }
}